home *** CD-ROM | disk | FTP | other *** search
- /* ********************************************************************
-
- FuncNames - A 'C' Function Listing Utility for MPW
-
- Version 1.0 January 12, 1989
-
- Copyright (c) 1989 by Scott Boag
-
- Changes and Additions to XC.C Copyright (c) 1989 by Scott Boag
-
- Scott Boag
- DMR Group Inc.
- 57 River Street
- Wellesly Hill, Massachusetts
- 02181
- (617) 237-0087
-
- Permission granted to copy for non-commercial purporses.
-
- --------------------------------------------------------
- Derived from:
-
- XC.C
-
- Version 1.0 January, 1982
-
- Copyright (c) 1982 by Philip N. Hisley
-
- Philip N. Hisley
- 548H Jamestown Court
- Edgewood, Maryland 21040
- (301) 679-4606
-
- Released for non-commercial distribution only
-
- Converted to IBM/PC CI/C86 by David N. Smith, May/June 1983
- with enhancements and Lattice compiler support in December 1983.
-
- David N. Smith
- 44 Ole Musket Lane
- Danbury, CT 06810
- (203) 748-5934
- CompuServe: 73145,153
-
- Changes Copyright (c) 1983 by David N. Smith
- Permission granted to copy for non-commercial purporses.
-
- PC Enhancements include:
-
- 1) Nested #INCLUDE statements
- 2) Single spaced cross-reference list
- 3) Removal of tabbing on output device
- (Since many printers don't support it)
- 4) #INCLUDE statements with both "--" and <-->
- syntax and with a full fileid in the quotes.
- 5) Multiple input filenames on command line.
-
-
-
-
- Minor additions by John Beamish, June 1984
-
- John Beamish
- Box 340, Station T
- Toronto, Ontario
- M6B 4A3
- (416) 782-1770
-
- Changes Copyright (c) 1984 by John Beamish.
- Permission granted to copy for non-commercial purposes.
-
- 1. Added reserved words ENUM and VOID.
- 2. Variable names extended to 31 characters.
- 3. Tab option on command line. Tabs are expanded to number
- of spaces specified in value with -t flag. Default is 4.
- 4. Cross-reference prints a blank line when the first
- character changes.
- 5. Command line errors reported in a more descriptive fashion.
- 6. Listing "tidied-up" and some comments added.
-
- --------------------------------------------------------
-
- A good way to see how this program works is to use it on itself.
- For example:
-
- FuncNames FuncNames.c -i > prn
-
- will run the program on itself, include the #include files
- and direct the output to the printer.
-
- Abstract:
-
- 'FuncNames' is primarly a function indexing utility and
- is meant to provide a printout or on-line reference
- to large source files. It is best used with the
- -f or -p flags set.
-
- 'FuncNames' is also a cross-reference utility for 'C' programs.
- It has the ability to handle nested include files
- to a depth of 8 levels and properly processes nested
- comments as supported by BDS C.
-
- Usage: FuncNames <filename> <flag(s)>
-
- Flags: -f = List function position by Files and Lines.
- -p = List functions position by Files, Lines, and pages.
- -m = List Macros along with functions.
- -x = Do Cross-reference (excludes function listing)
- -i = Enable file inclusion (dependent on -x being set)
- -l = Generate listing only (dependent on -x being set)
- -r = Cross-reference reserved words (dependent on -x being set)
- -o <outfile> = Write output to named file\n");
- -t <tab width> = Number of spaces to expand tabs\n");
- -w <width> = Width of output page\n\n");
-
- Note that flags -o -w -t must be followed by a space
- and then the value for the flag.
-
- ******************************************************************** */
-
- #include <types.h>
- #include <stdio.h>
- #include <ErrMgr.h>
- #include <Errors.h>
- #include <CursorCtl.h>
- #include <CType.h>
- #include <String.h>
- #include <Strings.h>
-
- /* Compiler specific stuff */
-
- /*
- #define Lattice
- #ifdef Lattice
- #include "e:ctype.h"
- #endif
- */
-
- /* end compiler specific section */
-
-
-
- /************************************************************************
- * #defines
- ************************************************************************/
- #ifndef TRUE
- #define TRUE 1
- #define FALSE 0
- #endif
-
- /* I use a Gemini 10X in compressed */
- /* print, 8 lpi most of the time. Using */
- /* this define allows me to use the */
- /* complete printed page for listings */
- /*
- #define PAGE_128X80
- */
- #ifdef PAGE_128X80
- #define LINES_PER_PAGE 80
- #define REFS_PER_LINE 15
- #define MAX_COL 128
- #else
- #define LINES_PER_PAGE 60 /* printed lines per page */
- #define REFS_PER_LINE 8 /* maximum refs per line */
- #define MAX_COL 78 /* default max col nmbr for listing line */
- #endif
-
- #define MIN_COL 30 /* minimum value for -w option */
- #define MIN_TAB 2
- #define MAX_TAB 10
- #define MAX_REF 5 /* maximum refs per ref-block */
- #define MAX_LEN 32 /* maximum identifier length */
- #define MAX_WRD 749 /* maximum number of identifiers */
- #define MAX_ALPHA 53 /* maximum alpha chain heads */
- #define ERROR -1
- #define FF 0x0C /* formfeed */
- #define TAB 4
- #define TABCHAR 0x09
- #define SPACECHAR 0x20
-
- #define OPENCURLY 0x7B
- #define CLOSECURLY 0x7D
- #define OPENPAREN 0x28
- #define CLOSEPAREN 0x29
- #define SEMICOLEN 0x3B
-
-
- /************************************************************************
- * Global_variables
- ************************************************************************/
- struct rf_blk {
- int ref_item[MAX_REF];
- char* ref_cnt;
- } onerf;
-
- struct id_blk {
- char id_name[MAX_LEN];
- int func_ref;
- struct id_blk *alpha_lnk;
- struct rf_blk *top_lnk;
- struct rf_blk *lst_lnk;
- } oneid;
-
- struct id_blk *id_vector[MAX_WRD];
-
- struct alpha_hdr {
- struct id_blk *alpha_top;
- struct id_blk *alpha_lst;
- };
-
- struct alpha_hdr alpha_vector[MAX_ALPHA];
-
- int pagno; /* page number */
- int paglin; /* page line counter */
- int linum; /* line number */
- int edtnum; /* edit line number */
- int fil_cnt; /* active file index */
- int wrd_cnt; /* token count */
- int id_cnt; /* number of unique identifiers */
- int rhsh_cnt; /* number of conflict hits */
- int filevl; /* file level */
- int dummy; /* dummy integer */
- int max_col=MAX_COL; /* maximum right column for listing line */
- int tab=TAB; /* standard tab expansion */
- int prt_ref;
-
- /* Variables local to this file */
-
- #define FBUFSIZ 8*BUFSIZ
-
- static Boolean optionsSpecified;
- static Boolean lineOption;
- static Boolean charOption;
- static char errorBuffer[256]; /* space to store text from GetSysErrText */
- static char filebuffer[FBUFSIZ]; /* buffer used for I/O */
-
- int echo_flag;
-
- int curlybrack_cnt;
- int parenbrack_cnt;
-
- int found_prob_func;
- int found_function;
-
- int found_macro;
- int wrote_macro;
-
- int func_count;
-
- int structflag;
-
- int defineflag;
-
- int continuedefineflag;
-
- int nofuncnameflag;
-
- int prevchar;
- int lastnonspacechar;
-
- char act_fil[MAX_LEN];
- char lst_fil[MAX_LEN];
- char gbl_fil[MAX_LEN];
- FILE *f_lst_fil;
- int i_flg,
- l_flg,
- o_flg,
- r_flg,
- f_flg,
- m_flg,
- p_flg;
-
-
- /************************************************************************
- * Prototypes.
- ************************************************************************/
- int main(int p_argc, char **p_argv);
- int lst_err(void);
- int use_err(int x, char* commandname);
- int proc_file(char *filnam, int incnum);
- void get_include_fileid(char *token, FILE *infile, char *filename, int linenumber);
- void echo(char c);
- void echochar(char c);
- int get_token(FILE *infile, char *g_token, int *g_toklen, int *g_eoflg, int g_flg);
- int fil_chr(FILE *infile, int *f_eof);
- int rdchr(FILE *infile, int *r_eoflg, int rd_flg);
- int chk_token(char *c_token);
- void put_token(char *p_token, int p_ref);
- void chain_alpha(struct id_blk *ca_ptr, char *ca_token);
- struct id_blk *alloc_id(char *aid_token);
- struct rf_blk *alloc_rf(int arf_ref);
- struct rf_blk *add_rf(struct rf_blk *adr_ptr, int adr_ref);
- void prnt_tbl(void);
- void prt_hdr(void);
- void nl(void);
- int abs(int i);
- long atoi(char *s);
- char *alloc(int i);
- void check_paren(char c);
-
- /* This should be declared somewhere, but I don't find it... */
- char* malloc(int i);
-
- /************************************************************************
- * Function: main
- ************************************************************************/
- int main(p_argc, p_argv)
- int p_argc;
- char **p_argv;
-
- {
- char *arg;
- int argc;
- char **argv;
- char c;
- int i;
- int fileliststart;
- long files;
- long parms;
-
- argc = p_argc;
- argv = p_argv;
- if (argc < 2){
- use_err('f', p_argv[0]);
- }
- files = func_count = 0;
- p_flg = m_flg = f_flg = i_flg=l_flg=o_flg=r_flg=FALSE;
- echo_flag = nofuncnameflag = TRUE;
- for (parms = 1; parms < argc; parms++) {
- if (*(arg=*++argv) != '-') {
- p_argv[++files] = p_argv[parms];
- }
- else {
- switch(*++arg) {
- case 'i':
- case 'I':
- /* -i = Enable file inclusion */
- i_flg++;
- break;
- case 'l':
- case 'L':
- /* -l = Generate listing only */
- l_flg++;
- break;
- case 'o':
- case 'O':
- /* -o <filename> = Write output to named file */
- {
- o_flg++;
- if (--argc == 0) {
- use_err('o', p_argv[0]);
- }
- strcpy(lst_fil,*++argv);
- if (lst_fil[0] == '-') {
- use_err('o', p_argv[0]);
- }
- break;
- }
- case 'r':
- case 'R':
- /* -r = Cross-ref reserved words */
- r_flg++;
- break;
- case 'x':
- case 'X':
- /* -f = do cross reference */
- nofuncnameflag = FALSE;
- echo_flag = FALSE;
- break;
- case 'p':
- case 'P':
- /* -p = list page numbers */
- p_flg++;
- break;
- case 'm':
- case 'M':
- /* -m = list macros */
- m_flg++;
- break;
- case 'f':
- case 'F':
- /* -f = list files and numbers */
- f_flg++;
- break;
- case 't':
- case 'T':
- /* -t <number> = Number of spaces to expand each tab */
- {
- if (--argc == 0) {
- use_err('t', p_argv[0]);
- }
- i = atoi(*++argv);
- if (i < MIN_TAB || i > MAX_TAB){
- use_err('t', p_argv[0]);
- }
- tab = i;
- break;
- }
- case 'w':
- case 'W':
- /* -w <width> = No of output columns */
- {
- if (--argc == 0) {
- use_err('w', p_argv[0]);
- }
- i = atoi(*++argv);
- if (i <= MIN_COL || i >= 255) {
- use_err('w', p_argv[0]);
- }
- max_col = i;
- break;
- }
-
- default:
- use_err('x', p_argv[0]);
- }
- }
- }
-
- if (o_flg) {
- if ((f_lst_fil=fopen(lst_fil,"w")) == NULL) {
- printf("ERROR: Unable to create list file - %s\n",lst_fil);
- exit(0);
- }
- printf("%s ... 'C' Function Lister Utility v1.0a\n\n", p_argv[0]);
- }
-
- /* initialize id_vector to NULL */
- for (linum=0; linum < MAX_WRD; linum++) {
- id_vector[linum] = NULL;
- }
-
- /* initialize alpha_vector[].top and alpha_vector[].alpha_lst to NULL */
- for (linum=0; linum < MAX_ALPHA; linum++) {
- alpha_vector[linum].alpha_top = alpha_vector[linum].alpha_lst = NULL;
- }
-
- /* More initialization. */
- prt_ref = FALSE;
- fil_cnt = wrd_cnt = linum = 0;
- filevl=paglin=pagno=edtnum=0;
- id_cnt=rhsh_cnt=0;
-
- /* Loop through each of the files in argument list. */
- argc = p_argc;
- argc--;
- argv = p_argv;
- for (parms = 1; parms <= files; parms++) {
- strcpy(gbl_fil,*++argv);
- /* If we run into a '-', then we know we've
- * hit a flag argument, so it's time to stop. */
- if (*gbl_fil == '-'){
- break;
- }
- /* and cross-ref the file. */
- proc_file(gbl_fil,dummy);
- }
-
- if(nofuncnameflag){
- if(files > 1){
- printf("### %d functions in %d files\n", func_count, files);
- }
- else if(files == 1){
- printf("### %d functions in file\n", func_count);
- }
- }
-
- if (!l_flg) {
- gbl_fil[0] = '\0';
- prnt_tbl();
- if(!echo_flag){
- printf("\nAllowable Symbols: %d\n",MAX_WRD);
- printf("Unique Symbols: %d\n",id_cnt);
- }
- }
- if (o_flg) {
- nl();
- /*
- if (fprintf(f_lst_fil,"%c",CPMEOF) == ERROR){
- lst_err();
- }
- */
- fclose(f_lst_fil);
- }
- }
-
- /************************************************************************
- * Function: lst_err
- ************************************************************************/
- int lst_err()
- {
- printf("\nERROR: Write error on list output file - %s\n", lst_fil);
- exit(0);
- }
-
- /************************************************************************
- * Function: use_err
- ************************************************************************/
- int use_err(x, commandname)
- int x;
- char* commandname;
- {
- printf("\nERROR: Invalid parameter specification. ");
- if (x == 'f')
- {
- printf("No/invalid input file name specified.");
- }
- else {
- if (x == 'x') {
- printf("Switch not recognized.");
- }
- else {
- printf("Error in switch %c.",x);
- }
- }
- printf("\n\nUsage: %s filename1 <filename2>... <flag(s)>\n\n", commandname);
- printf("Flags: -f = List function position by Files and Lines.\n");
- printf(" -p = List functions position by Files, Lines, and pages.\n");
- printf(" -m = List Macros along with functions.\n");
- printf(" -x = Do Cross-reference (excludes function listing)\n");
- printf(" -i = Enable file inclusion (dependent on -x being set)\n");
- printf(" -l = Generate listing only (dependent on -x being set)\n");
- printf(" -r = Cross-reference reserved words (dependent on -x being set)\n");
- printf(" -o <outfile> = Write output to named file\n");
- printf(" -t <tab width> = Number of spaces to expand tabs\n");
- printf(" -w <width> = Width of output page\n\n");
- printf("Flags must follow all input file names\n\n");
- printf("Flags -o, -t and -w must be followed by\n");
- printf("a space and then the value of the flag.\n\n");
- exit(0);
- }
-
- /************************************************************************
- * Function: printfuncline
- ************************************************************************/
- void printfuncline(filename, funcname, func_lineno, func_pageno, macroflag)
- char* filename;
- char* funcname;
- int func_lineno;
- int func_pageno;
- int macroflag;
- {
- char* nmstring = " ";
- char* mmstring = " (macro) ";
- char* mstring;
-
- if(macroflag){
- mstring = mmstring;
- }
- else {
- mstring = nmstring;
- }
- if(*funcname){
- if(p_flg){
- if (o_flg) {
- if (fprintf( f_lst_fil,
- "%-24.23s %s File %s ;\tLine %d; ##page %d\n",
- funcname, mstring, filename,
- func_lineno, func_pageno) == ERROR){
- lst_err();
- }
- *funcname = 0x00;
- }
- else {
- printf("%-24.23s %s File %s ; Line %d; \t##page %d\n",
- funcname, mstring, filename,
- func_lineno, pagno);
- }
- }
- else if(f_flg){
- if (o_flg) {
- if (fprintf( f_lst_fil,
- "%-24.23s %s File %s ; Line %d\n",
- funcname, mstring, filename,
- func_lineno) == ERROR){
- lst_err();
- }
- *funcname = 0x00;
- }
- else {
- printf( "%-24.23s %s File %s ; Line %d\n",
- funcname, mstring, filename, func_lineno);
- }
- }
- else {
- if (o_flg) {
- if (fprintf(f_lst_fil, "%s\n", funcname) == ERROR){
- lst_err();
- }
- *funcname = 0x00;
- }
- else {
- printf("%s\n", funcname);
- }
- }
- func_count++;
- }
- }
-
-
- /************************************************************************
- * Function: proc_file
- * Main cross-ref function.
- * (recursive)
- ************************************************************************/
- int proc_file(filnam,incnum)
- char *filnam; /* input filename. */
- int incnum; /* prev. included line nmbr (return to caller) */
- {
- char token[MAX_LEN]; /* token buffer */
- int eof_flg; /* end-of-file indicator */
- int tok_len; /* token length */
- FILE *infile; /* input file */
- char *worksp;
- char probable_func[MAX_LEN];
- int probable_func_lineno;
- int probable_func_pageno;
-
- strcpy(act_fil,filnam);
- edtnum=0;
- worksp=alloc(66);
- /*
- filnam=makefnam(filnam,".c",worksp);
- */
- if ((infile=fopen(filnam,"r")) == NULL) {
- printf("\nERROR: Unable to open input file: %s\n",filnam);
- return(incnum);
- }
- free(worksp); /* ??? */
- if (filevl++ == 0) {
- prt_hdr();
- }
- eof_flg = FALSE;
- parenbrack_cnt = curlybrack_cnt = 0;
- wrote_macro = found_macro = continuedefineflag = defineflag = structflag =
- found_function = found_prob_func = FALSE;
- *probable_func = 0x00;
- probable_func_pageno = probable_func_lineno = 0;
- if(nofuncnameflag){
- pagno = 1;
- }
- do {
- if (get_token(infile, token, &tok_len, &eof_flg, 0)){
- if (chk_token(token)) {
- if (!strcmp(token,"#include")) {
- get_include_fileid(token, infile, filnam, edtnum);
- if (!i_flg) {
- continue;
- }
- else {
- nl();
- edtnum=proc_file(token,edtnum);
- strcpy(act_fil,filnam);
- continue;
- }
- }
-
- if(nofuncnameflag && found_prob_func){
- strcpy(probable_func, token);
- probable_func_lineno = edtnum;
- probable_func_pageno = pagno;
- found_prob_func = FALSE;
- }
- if(defineflag && found_macro && m_flg && !wrote_macro) {
- printfuncline(filnam, token, edtnum, pagno, TRUE);
- found_macro = FALSE;
- wrote_macro = TRUE;
- }
- if(nofuncnameflag && found_function){
- printfuncline(filnam, probable_func, probable_func_lineno, probable_func_pageno, FALSE);
- found_function = FALSE;
- }
- if(!nofuncnameflag){
- put_token(token,linum);
- }
- }
- }
- else {
- if(nofuncnameflag && found_prob_func){
- strcpy(probable_func, token);
- probable_func_lineno = edtnum;
- probable_func_pageno = pagno;
- found_prob_func = FALSE;
- }
- }
- } while (!eof_flg);
-
- filevl -= 1;
- fclose(infile);
-
- return(incnum);
- }
-
- /************************************************************************
- * Function: check_paren
- ************************************************************************/
- void check_paren(c)
- char c;
- {
- switch(c){
- case OPENCURLY:
- if( (!curlybrack_cnt) &&
- (!parenbrack_cnt) &&
- (!defineflag) &&
- (!structflag)){
- found_function = TRUE;
- }
- curlybrack_cnt++;
- break;
- case CLOSECURLY:
- curlybrack_cnt--;
- if(!curlybrack_cnt) {
- found_prob_func = found_function = FALSE;
- }
- break;
- case OPENPAREN:
- if( (!curlybrack_cnt) &&
- (!parenbrack_cnt) &&
- (!defineflag) &&
- (!structflag)){
- found_prob_func = TRUE;
- }
- else if(defineflag && isalpha(prevchar) && (!parenbrack_cnt)){
- found_macro = TRUE;
- }
- parenbrack_cnt++;
- break;
- case CLOSEPAREN:
- parenbrack_cnt--;
- break;
- }
- if(!isspace(prevchar)) {
- lastnonspacechar == prevchar;
- }
- prevchar = c;
- return;
- }
-
- /************************************************************************
- * Function: get_include_fileid
- ************************************************************************/
- void get_include_fileid(token,infile, filename, linenumber)
- char *token;
- FILE *infile;
- char *filename;
- int linenumber;
- {
-
- char c, term;
-
- while (term=getc(infile)){
- if(!isspace(c)) {
- lastnonspacechar == c;
- }
- if(term == EOF){
- break;
- }
- echo(term);
- check_paren(term);
- if(term > SPACECHAR) {
- break;
- }
- }
-
- if ( term == '<' ) {
- term='>'; /* terminator is > or " */
- }
- if ( (term != '>') && (term!='"') ) {
- printf("Error scanning #INCLUDE fileid: %c; file %s; line %d\n",
- term, filename, linenumber);
- exit(1);
- }
-
- do {
- if ( (c = getc(infile)) != ' ') {
- check_paren(c);
- *token++ = c;
- echo(c);
- }
- else{
- echo(c);
- }
- } while ( c != term );
-
- *--token = '\0';
-
- }
-
- /************************************************************************
- * Function: echo
- ************************************************************************/
- void echo(c)
- char c;
- {
- static int col = 11;
- int i;
-
- if (c == '\t'){
- do{
- col++;
- echochar(' ');
- } while ((col <= max_col) && ((col % tab) != (11 % tab)));
- col--;
- }
- else {
- echochar(c);
- }
- if ( c == '\n' ){
- col = 11;
- }
- else if (++col > max_col) {
- col = 11;
- paglin++;
- echochar('\n');
- for (i=1; i <= 11; i++){
- echochar(' ');
- }
- }
- }
-
- /************************************************************************
- * Function: echochar
- ************************************************************************/
- void echochar(c)
- char c;
- {
- if (o_flg){
- if(!echo_flag){
- if (fprintf(f_lst_fil,"%c",c) == ERROR){
- lst_err();
- }
- }
- }
- else {
- if(!echo_flag){
- printf("%c",c);
- }
- }
- }
-
-
- /************************************************************************
- * Function: get_token
- * 'get_token' returns the next valid identifier or
- * reserved word from a given file along with the
- * character length of the token and an end-of-file
- * indicator
- ************************************************************************/
- int get_token(infile,g_token,g_toklen,g_eoflg,g_flg)
- FILE *infile;
- char *g_token;
- int *g_toklen;
- int *g_eoflg;
- int g_flg;
- {
- int c;
- char *h_token;
- char tmpchr;
-
- h_token = g_token;
-
- gtk:
- *g_toklen = 0;
- g_token = h_token;
-
- /*
- Scan and discard any characters until an alphabetic or
- '_' (underscore) character is encountered or an end-of-file
- condition occurs
- */
-
-
- while ((!isalpha(c = rdchr(infile, g_eoflg, g_flg)))
- && !*g_eoflg
- && c != '_'
- && c != '0'
- && c != '#'){
- if((c == OPENPAREN) && (!curlybrack_cnt) && (parenbrack_cnt == 1)){
- return(FALSE);
- }
- if((c == SEMICOLEN) && (!curlybrack_cnt) && structflag) {
- structflag = FALSE;
- }
- }
-
- *g_token = c;
-
- if (*g_eoflg) {
- return(FALSE);
- }
-
- *g_toklen += 1;
-
- /*
- Scan and collect identified alpanumeric token until
- a non-alphanumeric character is encountered or and
- end-of-file condition occurs
- */
-
- if (g_flg) {
- tmpchr = '.';
- }
- else {
- tmpchr = '_';
- }
-
- while ((isalpha(c=rdchr(infile,g_eoflg,g_flg))
- || isdigit(c)
- || c == '_'
- || c == tmpchr)
- && !*g_eoflg){
- if (*g_toklen < MAX_LEN) {
- *++g_token = c;
- *g_toklen += 1;
- }
- }
-
- /*
- Check to see if a numeric hex or octal constant has
- been encountered ... if so dump it and try again
- */
-
- if (*h_token == '0') {
- goto gtk;
- }
-
-
- /*
- Tack a NULL character onto the end of the token
- */
-
- *++g_token = NULL;
-
- /*
- Screen out all #token strings except #include
- */
- if (*h_token == '#' && strcmp(h_token,"#include")){
- if(!strncmp(h_token,"#define", 7)){
- defineflag = TRUE;
- }
- goto gtk;
- }
-
-
-
- return(TRUE);
- }
-
- /************************************************************************
- * Function: fil_chr
- * Get a character from the specified file, set f_eof flag to true if EOF.
- ************************************************************************/
- int fil_chr(infile,f_eof)
- FILE *infile;
- int *f_eof;
- {
- int fc;
-
- fc=getc(infile);
-
- if (fc == EOF) {
- *f_eof = TRUE;
- fc = NULL;
- }
- return(fc);
- }
-
- /************************************************************************
- * Function: rdchr
- * 'rdchr' returns the next valid character in a file
- * and an end-of-file indicator. A valid character is
- * defined as any which does not appear in either a
- * commented or a quoted string ... 'rdchr' will correctly
- * handle comment tokens which appear within a quoted
- * string
- ************************************************************************/
- int rdchr(infile, r_eoflg, rd_flg)
- int *r_eoflg;
- FILE *infile;
- int rd_flg;
- {
- int c;
- int q_flg; /* double quoted string flag */
- int q1_flg; /* single quoted string flag */
- int cs_flg; /* comment start flag */
- int ce_flg; /* comment end flag */
- int c_cnt; /* comment nesting level */
- int t_flg; /* transparency flag */
-
- q_flg = FALSE;
- q1_flg = FALSE;
- cs_flg = FALSE;
- ce_flg = FALSE;
- t_flg = FALSE;
- c_cnt = 0;
-
- rch:
-
- /*
- Fetch character from file
- */
-
- /* Get a character from the specified file, set f_eof flag to true if EOF. */
- c=fil_chr(infile,r_eoflg);
-
- if (*r_eoflg) {
- check_paren(c);
- return(c); /* EOF encountered */
- }
- if (c == '\n'){
- nl();
- }
- else {
- echo(c);
- }
-
- if (rd_flg){
- check_paren(c);
- return(c);
- }
-
- if (t_flg) {
- t_flg = !t_flg;
- goto rch;
- }
-
- if (c == '\\') {
- t_flg = TRUE;
- goto rch;
- }
- /*
- If the character is not part of a quoted string
- check for and process commented strings...
- nested comments are handled correctly but unbalanced
- comments are not ... the assumption is made that
- the syntax of the program being xref'd is correct
- */
-
- if (!q_flg && !q1_flg) {
- if (c == '*' && c_cnt && !cs_flg) {
- ce_flg = TRUE;
- goto rch;
- }
- if (c == '/' && ce_flg) {
- c_cnt -= 1;
- ce_flg = FALSE;
- goto rch;
- }
- ce_flg = FALSE;
- if (c == '/') {
- cs_flg = TRUE;
- goto rch;
- }
- if (c == '*' && cs_flg) {
- c_cnt += 1;
- cs_flg = FALSE;
- goto rch;
- }
- cs_flg = FALSE;
- if (c_cnt){
- goto rch;
- }
- }
-
- /*
- Check for and process quoted strings
- */
-
- if ( c == '"' && !q1_flg) {
- q_flg = !q_flg; /* toggle quote flag */
- goto rch;
- }
- if (q_flg){
- goto rch;
- }
-
- if (c == '\'') {
- q1_flg = !q1_flg; /* toggle quote flag */
- goto rch;
- }
- if (q1_flg) {
- goto rch;
- }
-
- /*
- Valid character ... return to caller
- */
- check_paren(c);
- return(c);
- }
-
- /************************************************************************
- * Function: chk_token
- ************************************************************************/
- int chk_token(c_token)
- char *c_token;
- {
- char u_token[MAX_LEN];
- int i;
-
- if (r_flg){
- return(TRUE);
- }
- i = 0;
- do {
- u_token[i] = toupper(c_token[i]);
- } while (c_token[i++] != NULL);
-
- switch(u_token[0]) {
- case 'A':
- if (strcmp(u_token,"AUTO") == 0)
- return(FALSE);
- break;
- case 'B':
- if (strcmp(u_token,"BREAK") == 0)
- return(FALSE);
- break;
- case 'C':
- if (strcmp(u_token,"CHAR") == 0)
- return (FALSE);
- if (strcmp(u_token,"CONTINUE") == 0)
- return (FALSE);
- if (strcmp(u_token,"CASE") == 0)
- return (FALSE);
- break;
- case 'D':
- if (strcmp(u_token,"DOUBLE") == 0)
- return(FALSE);
- if (strcmp(u_token,"DO") == 0)
- return(FALSE);
- if (strcmp(u_token,"DEFAULT") == 0)
- return(FALSE);
- break;
- case 'E':
- if (strcmp(u_token,"EXTERN") == 0)
- return(FALSE);
- if (strcmp(u_token,"ELSE") == 0)
- return(FALSE);
- if (strcmp(u_token,"ENTRY") == 0)
- return(FALSE);
- if (strcmp(u_token,"ENUM") == 0)
- return(FALSE);
- break;
- case 'F':
- if (strcmp(u_token,"FLOAT") == 0)
- return(FALSE);
- if (strcmp(u_token,"FOR") == 0)
- return(FALSE);
- break;
- case 'G':
- if (strcmp(u_token,"GOTO") == 0)
- return(FALSE);
- break;
- case 'I':
- if (strcmp(u_token,"INT") == 0)
- return(FALSE);
- if (strcmp(u_token,"IF") == 0)
- return(FALSE);
- break;
- case 'L':
- if (strcmp(u_token,"LONG") == 0)
- return(FALSE);
- break;
- case 'R':
- if (strcmp(u_token,"RETURN") == 0)
- return(FALSE);
- if (strcmp(u_token,"REGISTER") == 0)
- return(FALSE);
- break;
- case 'S':
- if (strcmp(u_token,"STRUCT") == 0) {
- return(FALSE);
- }
- if (strcmp(u_token,"SHORT") == 0)
- return(FALSE);
- if (strcmp(u_token,"STATIC") == 0)
- return(FALSE);
- if (strcmp(u_token,"SIZEOF") == 0)
- return(FALSE);
- if (strcmp(u_token,"SWITCH") == 0)
- return(FALSE);
- break;
- case 'T':
- if (strcmp(u_token,"TYPEDEF") == 0) {
- structflag = TRUE;
- return(FALSE);
- }
- break;
- case 'U':
- if (strcmp(u_token,"UNION") == 0)
- return(FALSE);
- if (strcmp(u_token,"UNSIGNED") == 0)
- return(FALSE);
- break;
- case 'V':
- if (strcmp(u_token,"VOID") == 0)
- return(FALSE);
- break;
- case 'W':
- if (strcmp(u_token,"WHILE") == 0)
- return(FALSE);
- break;
- }
- return(TRUE);
- }
-
- /************************************************************************
- * Function: put_token
- * Install parsed token and line reference in linked structure
- ************************************************************************/
- void put_token(p_token,p_ref)
- char *p_token;
- int p_ref;
- {
- int hsh_index;
- int i;
- int j;
- int d;
- int found;
- struct id_blk *idptr;
- struct rf_blk *rfptr;
- struct id_blk *alloc_id();
- struct rf_blk *alloc_rf();
- struct rf_blk *add_rf();
-
- if (l_flg){
- return;
- }
-
- /* Hashing algorithm is far from */
- /* optimal but is adequate for a */
- /* memory-bound index vector! */
- j=0;
- for (i=0; p_token[i] != NULL; i++) {
- j = j * 10 + p_token[i];
- }
- hsh_index = abs(j) % MAX_WRD;
- found = FALSE;
- d = 1;
- do {
- idptr = id_vector[hsh_index];
- if (idptr == NULL) {
- id_cnt++;
- idptr = id_vector[hsh_index] = alloc_id(p_token);
- chain_alpha(idptr,p_token);
- idptr->top_lnk = idptr->lst_lnk = alloc_rf(p_ref);
- found = TRUE;
- }
- else if (strcmp(p_token,idptr->id_name) == 0) {
- idptr->lst_lnk = add_rf(idptr->lst_lnk,p_ref);
- found = TRUE;
- }
- else {
- hsh_index += d;
- d += 2;
- rhsh_cnt++;
- if (hsh_index >= MAX_WRD) {
- hsh_index -= MAX_WRD;
- }
- if (d == MAX_WRD) {
- printf("\nERROR: Symbol table overflow\n");
- exit(0);
- }
- }
- } while (!found);
- }
-
- /************************************************************************
- * Function: chain_alpha
- ************************************************************************/
- void chain_alpha(ca_ptr,ca_token)
- struct id_blk *ca_ptr;
- char *ca_token;
- {
- char c;
- int f;
- struct id_blk *cur_ptr;
- struct id_blk *lst_ptr;
-
- c = ca_token[0];
- if (c == '_'){
- c = 0;
- }
- else if (isupper(c)) {
- c=1+((c-'A')*2);
- }
- else {
- c=2+((c-'a')*2);
- }
-
- if (alpha_vector[c].alpha_top == NULL) {
- alpha_vector[c].alpha_top = alpha_vector[c].alpha_lst = ca_ptr;
- ca_ptr->alpha_lnk = NULL;
- return;
- }
-
- /* check to see if new id_blk should be inserted between
- the alpha_vector header block and the first id_blk in
- the current alpha chain
- */
-
- if (strcmp(alpha_vector[c].alpha_top->id_name,ca_token) > 0) {
- ca_ptr->alpha_lnk=alpha_vector[c].alpha_top;
- alpha_vector[c].alpha_top=ca_ptr;
- return;
- }
-
- if (strcmp(alpha_vector[c].alpha_lst->id_name,ca_token) < 0) {
- alpha_vector[c].alpha_lst->alpha_lnk = ca_ptr;
- ca_ptr->alpha_lnk = NULL;
- alpha_vector[c].alpha_lst=ca_ptr;
- return;
- }
-
- cur_ptr = alpha_vector[c].alpha_top;
- while (strcmp(cur_ptr->id_name,ca_token) < 0) {
- lst_ptr = cur_ptr;
- cur_ptr = lst_ptr->alpha_lnk;
- }
-
- lst_ptr->alpha_lnk = ca_ptr;
- ca_ptr->alpha_lnk = cur_ptr;
- return;
- }
-
- /************************************************************************
- * Function: alloc_id
- ************************************************************************/
- struct id_blk *alloc_id(aid_token)
- char *aid_token;
- {
- int ai;
- struct id_blk *aid_ptr;
-
- if ((aid_ptr = alloc(sizeof(struct id_blk))) == 0)
- {
- printf("\nERROR: Unable to allocate identifier block\n");
- exit(0);
- }
- ai=0;
- do {
- aid_ptr->id_name[ai] = aid_token[ai];
- } while (aid_token[ai++] != NULL);
-
- return (aid_ptr);
- }
-
- /************************************************************************
- * Function: alloc_rf
- ************************************************************************/
- struct rf_blk *alloc_rf(arf_ref)
- int arf_ref;
- {
- int ri;
- struct rf_blk *arf_ptr;
-
- if ((arf_ptr = alloc(sizeof(struct rf_blk))) == 0) {
- printf("\nERROR: Unable to allocate reference block\n");
- exit(0);
- }
- arf_ptr->ref_item[0] = arf_ref;
- arf_ptr->ref_cnt = (char*)1;
- for (ri=1;ri<MAX_REF;ri++) {
- arf_ptr->ref_item[ri] = NULL;
- }
- return (arf_ptr);
- }
-
- /************************************************************************
- * Function: add_rf
- ************************************************************************/
- struct rf_blk *add_rf(adr_ptr,adr_ref)
- struct rf_blk *adr_ptr;
- int adr_ref;
- {
- struct rf_blk *tmp_ptr;
-
- tmp_ptr = adr_ptr;
- if (adr_ptr->ref_cnt == (char*)MAX_REF) {
- tmp_ptr = adr_ptr->ref_cnt = (char*)alloc_rf(adr_ref);
- }
- else{
- adr_ptr->ref_item[(int)(adr_ptr->ref_cnt++)] = adr_ref;
- }
- return (tmp_ptr);
- }
-
- /************************************************************************
- * Function: prnt_tbl
- ************************************************************************/
- void prnt_tbl()
- {
- int prf_cnt;
- int pti;
- int pref;
- int lin_cnt;
- char save_1st;
- struct id_blk *pid_ptr;
- struct rf_blk *ptb_ptr;
- int saved_echo_flag;
-
- save_1st = NULL;
- prt_ref = TRUE;
- prt_hdr();
- saved_echo_flag = echo_flag;
- /* echo_flag = FALSE; */
- for (pti=0;pti<MAX_ALPHA;pti++) {
- if ((pid_ptr = alpha_vector[pti].alpha_top) != NULL) {
- do {
- if (save_1st != pid_ptr->id_name[0]) {
- if(!nofuncnameflag){
- nl();
- }
- save_1st = pid_ptr->id_name[0];
- }
- if ((!echo_flag) && o_flg) {
- if (fprintf(f_lst_fil,"%-33.32s: ",pid_ptr->id_name) == ERROR){
- lst_err();
- }
- }
- else if(!echo_flag){
- printf("%-33.32s: ",pid_ptr->id_name);
- }
- ptb_ptr=pid_ptr->top_lnk;
- lin_cnt=prf_cnt=0;
- do {
- if (prf_cnt == MAX_REF) {
- prf_cnt=0;
- ptb_ptr = (struct rf_blk *)ptb_ptr->ref_cnt;
- }
- if (((int)ptb_ptr) > MAX_REF) {
- if ((pref=ptb_ptr->ref_item[prf_cnt++]) != 0) {
- if (o_flg) {
- if ((!echo_flag) && (fprintf(f_lst_fil,"%4d ",pref) == ERROR)) {
- lst_err();
- }
- }
- else if(!echo_flag){
- printf("%4d ",pref);
- }
- if (++lin_cnt == REFS_PER_LINE) {
- if(!nofuncnameflag){
- nl();
- if ((!echo_flag) && o_flg) {
- if (fprintf(f_lst_fil," ") == ERROR) {
- lst_err();
- }
- }
- else if(!echo_flag){
- printf(" ");
- }
- }
- lin_cnt=0;
- }
-
- }
- }
- else {
- pref=0;
- }
- } while (pref);
- nl();
- } while ((pid_ptr=pid_ptr->alpha_lnk) != NULL);
- }
- }/*for*/
-
- echo('\n');
- echo_flag = saved_echo_flag;
- }
-
- /************************************************************************
- * Function: prt_hdr
- ************************************************************************/
- void prt_hdr()
- {
- if (pagno++ != 0) {
- if(!nofuncnameflag){
- echo('\n');
- echo( FF );
- }
- }
- if (o_flg){
- if(!nofuncnameflag){
- if (fprintf(f_lst_fil, "XC ... 'C' Concordance Utility %-20s Page %d",
- gbl_fil,pagno) == ERROR){
- lst_err();
- }
- }
- }
- else {
- if(!nofuncnameflag){
- printf("XC ... 'C' Concordance Utility %-20s Page %d",gbl_fil,pagno);
- }
- }
- if(!nofuncnameflag){
- echo('\n');
- }
- paglin = 3;
- nl();
- }
-
- /************************************************************************
- * Function: nl
- ************************************************************************/
- void nl()
- {
- echo('\n');
- if (++paglin >= LINES_PER_PAGE) {
- prt_hdr();
- }
- else if (!prt_ref) {
- if(defineflag && (lastnonspacechar != 0x5C)){
- defineflag = FALSE;
- wrote_macro = FALSE;
- }
- if (o_flg) {
- if(!echo_flag){
- if (fprintf(f_lst_fil,"%-4d %4d: ", ++linum,++edtnum) == ERROR){
- lst_err();
- }
- }
- else {
- ++linum; ++edtnum;
- }
- }
- else {
- if(!echo_flag){
- printf("%-4d %4d: ", ++linum,++edtnum);
- }
- else {
- ++linum; ++edtnum;
- }
- }
- if (o_flg){
- if (linum % 60 == 1) {
- if(!echo_flag){
- printf("\n<%4d> ",linum);
- }
- }
- else {
- if(!echo_flag){
- printf(".");
- }
- #ifdef Lattice
- fflush(stdout);
- #endif
- }
- }
-
- }
- return;
- }
-
- /************************************************************************
- * Function: abs
- ************************************************************************/
- #ifndef Lattice
- int abs(i)
- int i;
- {
- if (i<0)
- return(-i);
- else
- return( i);
- }
- #endif
-
- /************************************************************************
- * Function: atoi
- * cvt ascii to int or long
- ************************************************************************/
- #ifdef Lattice
- long atoi(s)
- char *s;
- {
- long n;
- int sign = 0;
-
- while (*s==' ' || *s=='\t')
- ++s; /* move over blanks & tabs */
- if (*s=='-')
- sign=1;
- else
- if (*s!='+')
- --s;
- ++s; /* skip sign */
- for (n=0; *s >= '0' && *s<='9'; )
- n = n * 10 + (*s++ - '0');
- if (sign)
- n = -n;
- return n;
- }
- #endif
-
- /************************************************************************
- * Function: alloc
- ************************************************************************/
- char* alloc(i)
- int i;
- {
- return(malloc(i));
- }
-
-